/*
 * @(#)SpringInvoker.java $version 2010. 8. 11
 *
 * Copyright 2007-2010 NHN Corp. All rights Reserved. 
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.nhncorp.usf.core.invoker;

import javax.management.RuntimeErrorException;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.nhncorp.lucy.common.container.SpringBeanFactory;
import com.nhncorp.usf.core.call.DefaultCall;
import com.nhncorp.usf.core.call.DefaultFault;
import com.nhncorp.usf.core.call.Reply;
import com.nhncorp.usf.core.exception.CallExecutorException;
import com.nhncorp.usf.core.normalizer.DefaultObjectNormalizer;
import com.nhncorp.usf.core.ognl.OgnlCallExecutor;
import com.nhncorp.usf.core.ognl.SpsFaultPolicy;
import com.nhncorp.usf.core.service.ServiceRegistry;

/**
 * @author Web Platform Development Team
 */
public class SpringInvoker implements Invoker {
    private final OgnlCallExecutor executor = new OgnlCallExecutor();
	private ServiceRegistry serviceRegistry = null;

    /**
	 * Instantiates a new lucy invoker.
	 */
	public SpringInvoker() {
		serviceRegistry = new SpringServiceRegistry();
	}

    /**
	 * Gets the service registry.
	 *
	 * @return the service registry
	 */
	protected ServiceRegistry getServiceRegistry() {
		return serviceRegistry;
	}

    /**
	 * The Class LucyServiceRegistry.
	 */
	private static final class SpringServiceRegistry implements ServiceRegistry {
		public SpringServiceRegistry() {
			ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext*.xml");
			SpringBeanFactory.init(applicationContext);
		}
		public Object getService(String name) {
			try {
				return SpringBeanFactory.getBean(name);
			} catch (NoSuchBeanDefinitionException e) {
				e.printStackTrace();
				throw new RuntimeException(e.getMessage());
			}
		}
	}

    /**
	 * get Business Object from Spring Container and invoke method of it using
	 * Reflection.
	 *
	 * @param objectName identifier of business object
	 * @param methodName method to be invoked
	 * @param params parameters to invoke method
	 *
	 * @return the invocation future
	 */
	public InvocationFuture invoke(String objectName, String methodName, Object... params) {
		DefaultInvocationFuture future = new DefaultInvocationFuture();
		Reply reply = null;

		try {
			DefaultCall call = new DefaultCall();
			call.setObjectName(objectName);
			call.setMethodName(methodName);
			call.setParameters(params);

			reply = executor.execute(serviceRegistry, call);
		} catch (CallExecutorException e) {
			reply = new DefaultFault(SpsFaultPolicy.getCode(e), e.getMessage(), new DefaultObjectNormalizer().normalize(e));
		}

		future.setReady(reply);

		return future;
	}

	/**
	 * dispose invoker.
	 */
	public void dispose() {
		return;
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isValid() {
		return true;
	}

}
